/**
 * API service tests
 */

import * as apiService from '../../src/services/api';

// Mock the entire API service
jest.mock('../../src/services/api', () => ({
  authApi: {
    login: jest.fn(),
    getCurrentUser: jest.fn(),
    validateToken: jest.fn(),
    refreshToken: jest.fn(),
    logout: jest.fn(),
  },
  telemetryApi: {
    getTelemetryStats: jest.fn(),
    getTelemetryPoints: jest.fn(),
    createTelemetryPoint: jest.fn(),
    updateTelemetryPoint: jest.fn(),
    deleteTelemetryPoint: jest.fn(),
  },
  teamApi: {
    getTeams: jest.fn(),
    createTeam: jest.fn(),
    updateTeam: jest.fn(),
    deleteTeam: jest.fn(),
  },
  searchApi: {
    search: jest.fn(),
    getSuggestions: jest.fn(),
    getComponents: jest.fn(),
    getTokens: jest.fn(),
  },
  directoryApi: {
    getDirectory: jest.fn(),
    getDirectoryItems: jest.fn(),
  },
  analysisApi: {
    getAnalysis: jest.fn(),
    startAnalysis: jest.fn(),
    getAnalysisResults: jest.fn(),
  }
}));

// Mock localStorage
const localStorageMock = {
  getItem: jest.fn(),
  setItem: jest.fn(),
  removeItem: jest.fn(),
  clear: jest.fn(),
};
Object.defineProperty(window, 'localStorage', { value: localStorageMock });

// Import the mocked APIs
const { authApi, telemetryApi, teamApi, searchApi, directoryApi, analysisApi } = apiService as any;

describe('API Services', () => {
  beforeEach(() => {
    jest.clearAllMocks();
    localStorageMock.clear();
  });

  describe('Authentication API', () => {
    describe('login', () => {
      it('should login successfully with credentials', async () => {
        const mockResponse = {
          success: true,
          user: {
            user_id: 'test-user-123',
            email: 'test@example.com',
            name: 'Test User'
          },
          token: 'test-token-123',
          message: 'Authentication successful'
        };

        (authApi.login as jest.Mock).mockResolvedValue(mockResponse);

        const result = await authApi.login({
          username: 'testuser',
          password: 'testpass'
        });

        expect(authApi.login).toHaveBeenCalledWith({
          username: 'testuser',
          password: 'testpass'
        });
        expect(result).toEqual(mockResponse);
      });

      it('should handle login failure', async () => {
        const mockError = new Error('Invalid credentials');
        (authApi.login as jest.Mock).mockRejectedValue(mockError);

        await expect(authApi.login({
          username: 'wronguser',
          password: 'wrongpass'
        })).rejects.toThrow('Invalid credentials');
      });
    });

    describe('getCurrentUser', () => {
      it('should get current user information', async () => {
        const mockUser = {
          user_id: 'test-user-123',
          email: 'test@example.com',
          name: 'Test User'
        };

        (authApi.getCurrentUser as jest.Mock).mockResolvedValue(mockUser);

        const result = await authApi.getCurrentUser();

        expect(authApi.getCurrentUser).toHaveBeenCalled();
        expect(result).toEqual(mockUser);
      });
    });
  });

  describe('Telemetry API', () => {
    describe('getTelemetryStats', () => {
      it('should get telemetry statistics', async () => {
        const mockStats = {
          totalPoints: 1500,
          analyzedPoints: 1200,
          pendingPoints: 300,
          componentCount: 45
        };

        (telemetryApi.getTelemetryStats as jest.Mock).mockResolvedValue(mockStats);

        const result = await telemetryApi.getTelemetryStats();

        expect(telemetryApi.getTelemetryStats).toHaveBeenCalled();
        expect(result).toEqual(mockStats);
      });
    });

    describe('getTelemetryPoints', () => {
      it('should get telemetry points with pagination', async () => {
        const mockPoints = {
          points: [
            {
              id: 'point-1',
              name: 'test.metric.1',
              type: 'histogram',
              component: 'test-component'
            }
          ],
          total: 100,
          page: 1,
          pageSize: 10
        };

        (telemetryApi.getTelemetryPoints as jest.Mock).mockResolvedValue(mockPoints);

        const result = await telemetryApi.getTelemetryPoints({
          page: 1,
          pageSize: 10
        });

        expect(telemetryApi.getTelemetryPoints).toHaveBeenCalledWith({
          page: 1,
          pageSize: 10
        });
        expect(result).toEqual(mockPoints);
      });
    });
  });

  describe('Search API', () => {
    describe('search', () => {
      it('should search telemetry points', async () => {
        const mockSearchResult = {
          results: [
            {
              id: 'point-1',
              name: 'test.metric.1',
              type: 'histogram'
            }
          ],
          total: 1,
          query: 'test'
        };

        (searchApi.search as jest.Mock).mockResolvedValue(mockSearchResult);

        const result = await searchApi.search('test', {
          type: 'histogram'
        });

        expect(searchApi.search).toHaveBeenCalledWith('test', {
          type: 'histogram'
        });
        expect(result).toEqual(mockSearchResult);
      });
    });
  });

  describe('Team API', () => {
    describe('getTeams', () => {
      it('should get all teams', async () => {
        const mockTeams = [
          {
            id: 'team-1',
            name: 'Test Team',
            member_count: 5
          }
        ];

        (teamApi.getTeams as jest.Mock).mockResolvedValue(mockTeams);

        const result = await teamApi.getTeams();

        expect(teamApi.getTeams).toHaveBeenCalled();
        expect(result).toEqual(mockTeams);
      });
    });
  });

  describe('Directory API', () => {
    describe('getDirectory', () => {
      it('should get directory structure', async () => {
        const mockDirectory = {
          path: '/src/components',
          items: [
            {
              name: 'Button.tsx',
              type: 'file'
            }
          ]
        };

        (directoryApi.getDirectory as jest.Mock).mockResolvedValue(mockDirectory);

        const result = await directoryApi.getDirectory('/src/components');

        expect(directoryApi.getDirectory).toHaveBeenCalledWith('/src/components');
        expect(result).toEqual(mockDirectory);
      });
    });
  });

  describe('Analysis API', () => {
    describe('getAnalysis', () => {
      it('should get analysis results', async () => {
        const mockAnalysis = {
          id: 'analysis-1',
          status: 'completed',
          results: {
            metrics: 10,
            issues: 2
          }
        };

        (analysisApi.getAnalysis as jest.Mock).mockResolvedValue(mockAnalysis);

        const result = await analysisApi.getAnalysis('analysis-1');

        expect(analysisApi.getAnalysis).toHaveBeenCalledWith('analysis-1');
        expect(result).toEqual(mockAnalysis);
      });
    });
  });
});